iT邦幫忙

2025 iThome 鐵人賽

DAY 5
1
Vue.js

打造銷售系統30天修練 - 全集中・Vue之呼吸系列 第 5

Day 5:[Vueの呼吸・肆之型] 初探 Vue API - 前後端分離的介面規劃

  • 分享至 

  • xImage
  •  

前後端分離與 API 設計

在現代的系統開發中,前後端分離API 設計幾乎已經成為必備的基礎觀念。本文將以我們的 Vue 銷售系統為例,說明什麼是前後端分離、API 的角色,以及如何一步一步從介面設計推導出清晰的 API 規劃。


什麼是「前後端分離」?

前後端分離簡單來說,就是讓「前端」與「後端」各自專注於自己的職責,並透過 API 互相溝通:

  • 前端 (Frontend)
    例如我們正在開發的 Vue 應用程式,負責 使用者看得到、摸得到的介面與互動

  • 後端 (Backend)
    伺服器端程式,負責 業務邏輯、資料庫操作、資料的儲存


API 的角色:前後端的橋樑

API (Application Programming Interface) 的功能,就像一座「橋樑」:

  • 前端 → 透過 API 發送請求來獲取或更新資料。
  • 後端 → 透過 API 回應資料,提供給前端顯示。

沒有 API,前後端就無法有效地協作。


從使用者介面反推 API 需求

主畫面

設計 API 的第一步,就是觀察系統的每一個頁面,並問自己:

  1. 「這個頁面需要『看』什麼資料?」
    → 決定我們需要哪些 GET API

  2. 「使用者可以在這個頁面『做』什麼事?」
    → 決定我們需要哪些 POST、PUT、DELETE API

這種方式可以讓我們的 API 與實際需求緊密結合,避免冗餘設計。


客戶管理 (Customer Management)

這邊我們以客戶管理的這個介面來設計我們所需要的 API 有哪些

https://ithelp.ithome.com.tw/upload/images/20250905/2017769470Yt5InCNf.png

  • 搜尋客戶資訊
  • 客戶的讀取、建立、修改等操作

對應 API:

  • GET /customers/search?keyword=xxx → 根據關鍵字搜尋客戶
  • GET /customers → 取得客戶列表
  • GET /customers/{id} → 取得單一客戶詳細資料
  • POST /customers → 新增客戶
  • PUT /customers/{id} → 更新客戶資料
  • DELETE /customers/{id} → 刪除客戶

API 格式與規範

在系統開發中,前端和後端需要約定好「溝通的規則」,否則可能會出現很多問題。

為什麼需要規定格式?

1. 前後端能夠順利溝通

前端要知道後端回傳的資料長什麼樣子,才能正確顯示給使用者。

後端也要知道前端傳來的資料結構,才能正確處理請求。

2. 維護與擴充容易

如果每個 API 回傳的格式都不一樣,未來加新功能時就會非常容易出錯。

統一格式後,前端可以寫「通用的資料處理程式」,不必為每個 API 寫不同邏輯。

方便處理成功與失敗情況,且統一的回傳結構可以讓前端快速判斷操作是否成功,並顯示相應訊息。


  • 資料格式:統一使用 JSON

  • 回應結構

    • success:表示這次 API 操作是否成功

    • data:成功時真正的資料放在這裡

    • error:失敗時提供錯誤資訊,包括錯誤碼與訊息

成功回應:


{
  "success": true,
  "data": { ... } 
}

失敗回應:


{
  "success": false,
  "error": {
    "code": "ERROR_CODE",
    "message": "錯誤訊息"
  }
}

在 Vue 中如何使用 API?

在 Vue 中,API 通常不會直接寫在模板裡,而是透過 封裝的函式或服務 去呼叫。這樣做的好處:

  • 統一管理 API:所有請求集中在同一個檔案或資料夾,方便維護。

  • 減少重複程式碼:前端組件不需要重複寫 fetch 或 axios 邏輯。

  • 方便處理錯誤與統一格式:統一處理 API 成功、失敗回傳,前端可以快速判斷並顯示訊息。

  1. 封裝 API
// api/customers.js
import axios from 'axios';

const BASE_URL = 'https://your-api.com';

export const getCustomers = () => axios.get(`${BASE_URL}/customers`);
export const getCustomerById = (id) => axios.get(`${BASE_URL}/customers/${id}`);
export const createCustomer = (data) => axios.post(`${BASE_URL}/customers`, data);
export const updateCustomer = (id, data) => axios.put(`${BASE_URL}/customers/${id}`, data);
export const deleteCustomer = (id) => axios.delete(`${BASE_URL}/customers/${id}`);

  1. 在組件中呼叫 API
<template>
  <div>
    <ul>
      <li v-for="customer in customers" :key="customer.id">{{ customer.name }}</li>
    </ul>
  </div>
</template>

<script>
import { ref, onMounted } from 'vue';
import { getCustomers } from '@/api/customers';

export default {
  setup() {
    const customers = ref([]);

    onMounted(async () => {
      try {
        const response = await getCustomers();
        if (response.data.success) {
          customers.value = response.data.data;
        }
      } catch (error) {
        console.error('API 錯誤', error);
      }
    });

    return { customers };
  }
};
</script>

  1. 全域狀態管理

對於多個組件共用資料(如報價單、客戶列表),可以使用我們前面提過的 Pinia

// store/customers.js (Pinia)
import { defineStore } from 'pinia';
import { getCustomers } from '@/api/customers';

export const useCustomerStore = defineStore('customer', {
  state: () => ({
    customers: [],
  }),
  actions: {
    async fetchCustomers() {
      const response = await getCustomers();
      if (response.data.success) this.customers = response.data.data;
    }
  }
});

在組件中只需要:

const customerStore = useCustomerStore();
await customerStore.fetchCustomers();

這樣組件就可以只顯示資料,不處理 API 邏輯,方便多組件共享狀態。

總結

今天,我們完整地將前後端分離與 API 設計的概念,從觀察使用者介面出發,應用到我們的 銷售系統中。

  1. 判斷資料需求 → 明確知道每個頁面需要哪些資料(GET API)。

  2. 定義使用者操作 → 決定使用者可以執行哪些動作(POST、PUT、DELETE API)。

  3. 封裝 API → 將系統功能對應到清晰、易懂的 API 端點,並統一管理。

  4. 在 Vue 中使用 → 組件只專注顯示資料,API 呼叫由封裝函式或全域狀態管理處理。

  5. 統一資料格式與回應規範 → 使用 JSON 統一回傳結構,方便前端快速處理成功與失敗情況。

明日,我們將進入 Day 6:[Vueの呼吸・伍之型] Vue基礎 - 響應式原理與實作,了解 Vue 的響應式原理。 心を燃やせ !!


上一篇
Day 4:[Vueの呼吸・參之型] 初探路由架構 - 多角色的Navigation設計
系列文
打造銷售系統30天修練 - 全集中・Vue之呼吸5
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言